<template>
    <el-container>
        <el-main style="padding: 0">
            <el-row>
                <el-col :span="19" style="display: flex;justify-content: space-between">
                    <el-input v-model="search_proc" prefix-icon="Search" placeholder="type procName" size="small">

                    </el-input>
                    <el-button size="small" @click="get_proc">
                        搜索
                    </el-button>
                    <el-tag type="danger">左侧为进程id 右侧为对应进程的包 单击显示包详细信息 双击显示一个完整的对话</el-tag>
                </el-col>
                <el-col :span="1"><el-text tag="b" type="primary" style="float:right;">{{ show_type }}</el-text></el-col>
                <el-col :span="2">
                    <el-button style="float: right" type="danger" size="small" @click="return_global">返回全局</el-button>
                </el-col>
                <el-col :span="2">
                    <el-dropdown split-button type="primary" size="small">
                        菜单
                        <template #dropdown>
                            <el-dropdown-menu>
                                <el-dropdown-item @click.native="devices_visible = true">选择设备</el-dropdown-item>
                                <el-dropdown-item @click="clear_this">清空屏幕</el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>

                    <el-dialog v-model="devices_visible" title="选择需要监听的设备">
                        <template #header style="padding: 0">
                            <el-tag type="danger" size="large" style="padding: 0;font-size: 13px">如果你知道包即将前往哪个设备</el-tag>
                        </template>
                        <el-main style="padding: 0">
                            <el-row v-for="(item, index) in all_devices" >
                                <el-col :span="24">
                                    <div style="display: inline-flex;align-items: center;margin-top: 6px">
                                        <el-text tag="b" type="primary">{{ item.Description }}</el-text>
                                    </div>
                                    <el-switch v-model="select_devices[index]" border style="float: right" @change="handel_dev_change"></el-switch>
                                </el-col>
                            </el-row>
                        </el-main>
                    </el-dialog>
                </el-col>
            </el-row>
            <el-row style="margin-top: 5px">
                <el-col :span="3">
                    <div style="border-radius: 2px;border-right: 1px solid black;text-align: center">
                        <el-scrollbar height="91vh">
                            <el-tree ref="tree" :data="proc_data" draggable show-checkbox
                                     @check-change="tree_check_change" node-key="id">
                                <template v-slot="{node}">
                                    <el-text tag="b">{{ node.label.split('-')[1] }}</el-text>
                                </template>
                            </el-tree>
                        </el-scrollbar>
                    </div>
                </el-col>
                <el-col :span="21">
                    <el-main style="padding: 0">
                        <el-row>
                            <el-col style="height: 88vh">
                                <div v-for="(item, index) in page_list" :key="index"
                                     style="display: flex;justify-content: space-between">
                                    <el-button
                                            v-if="item.SrcIp.startsWith('192.168.')"
                                            type="success"
                                            style="margin-left: auto;padding: 0;font-size: 13px"
                                            size="small"
                                            @click="show_chat(item)"
                                            @dblclick="db_show_chat(item)">
                                        {{ item.Pid }} -> {{ item.SrcIp }}:{{ item.SrcPort }} -> {{ item.Protocol }}
                                    </el-button>
                                    <el-button
                                            v-if="!item.SrcIp.startsWith('192.168.')"
                                            type="primary"
                                            style="margin-right: auto;padding: 0;font-size: 13px"
                                            size="small"
                                            @click="show_chat(item)"
                                            @dblclick="db_show_chat(item)">
                                        {{ item.Pid }} -> {{ item.SrcIp }}:{{ item.SrcPort }} -> {{ item.Protocol }}
                                    </el-button>
                                </div>
                                <el-dialog v-model="package_detail_visible" title="单击文本 显示详情">
                                    <el-main>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">Src </el-tag>
                                            <el-text style="width: 340px;margin-left: 5px" truncated>
                                                {{ show_detail.SrcIp + ':' + show_detail.SrcPort }}
                                            </el-text>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">Dst </el-tag>
                                            <el-text style="width: 340px;margin-left: 5px" truncated>
                                                {{ show_detail.DstIp + ':' + show_detail.DstPort }}
                                            </el-text>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">Window </el-tag>
                                            <el-text style="width: 340px;margin-left: 5px" truncated>
                                                {{ show_detail.Window }}
                                            </el-text>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">Protocol </el-tag>
                                            <el-text style="width: 340px;margin-left: 5px" truncated>
                                                {{ show_detail.Protocol }}&nbsp;{{show_detail.Method}}
                                            </el-text>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">From </el-tag>
                                            <el-tooltip placement="top">
                                                <template #content>
                                                    <el-text style="color: white">
                                                        {{ show_detail.DeviceDescription}}【{{ show_detail.DeviceName }}】{{'->' + show_detail.Pid}}
                                                    </el-text>
                                                </template>
                                                <el-text style="width: 340px;margin-left: 5px" truncated
                                                         @click="show_content(show_detail.DeviceDescription + '【' + show_detail.DeviceName + '】 -> ' + show_detail.Pid)">
                                                    {{ show_detail.DeviceDescription}}【{{ show_detail.DeviceName }}】{{'->' + show_detail.Pid}}
                                                </el-text>
                                            </el-tooltip>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">DataBytes </el-tag>
                                            <el-tooltip :content="show_detail.data_bytes" placement="top">
                                                <template #content>
                                                    <el-text style="color: white">{{ show_detail.data_bytes }}</el-text>
                                                </template>
                                                <el-text style="width: 340px;margin-left: 5px" truncated @click="show_content(show_detail.data_bytes)">
                                                    {{ show_detail.data_bytes }}
                                                </el-text>
                                            </el-tooltip>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">Data </el-tag>
                                            <el-tooltip placement="top">
                                                <template #content>
                                                    <el-text style="color: white">{{ show_detail.Data }}</el-text>
                                                </template>
                                                <el-text style="width: 340px;margin-left: 5px" truncated @click="show_content(show_detail.Data)">
                                                    {{ show_detail.Data }}
                                                </el-text>
                                            </el-tooltip>
                                        </el-row>
                                        <el-row>
                                            <el-tag style="width: 70px;padding: 0;font-size: 15px" type="danger">DataString </el-tag>
                                            <el-tooltip placement="top" >
                                                <template #content>
                                                    <el-text style="color: white" v-html="show_detail.DataString"></el-text>
                                                </template>
                                                <el-text style="width: 340px;margin-left: 5px" truncated @click="show_content(show_detail.DataString)">
                                                    {{ show_detail.DataString }}
                                                </el-text>
                                            </el-tooltip>
                                        </el-row>
                                        <el-dialog v-model="content_visible" title="详细">
                                            <el-text v-html="content_dialog">
                                            </el-text>
                                        </el-dialog>
                                    </el-main>
                                </el-dialog>
                            </el-col>
                            <el-col style="display: flex;justify-content: center">
                                <el-pagination
                                        small
                                        @current-change="cur_change"
                                        :current-page="cur_page"
                                        :page-size="22"
                                        layout="total, prev, pager, next, jumper"
                                        :total="parseInt(show_message_list.length)"
                                >
                                </el-pagination>
                            </el-col>
                        </el-row>
                    </el-main>
                </el-col>
            </el-row>
        </el-main>
    </el-container>
</template>

<script lang="ts">
    import {GetAllDevices, GetProcIdByName, SetNeedDevices, SetSelectPid} from "../../wailsjs/go/main/App";
    import {EventsOn} from "../../wailsjs/runtime";
    import {ElMessage} from "element-plus";

    export default {
        name: 'HomeView',
        created() {
            this.append_log()
            GetAllDevices().then(res => {
                this.all_devices = res
                for (let i in this.all_devices) {
                    this.select_devices.push(true)
                }
            })
        },
        mounted() {

        },
        updated() {
        },
        data() {
            return {
                search_proc: '',
                proc_data: [],
                search_inter: 0,
                message_list: [],
                show_message_list:[], //真正显示的msg list
                show_key: '', // 显示的会话key
                page_list: [],
                cur_page: 1,
                page_save: 1, //切换会话前保存的页标
                show_type: '全局',
                chat_map: {}, // lip:lport-rip:rport -> Package
                devices_visible: false,
                all_devices: [],
                select_devices: [],
                click_timer: 0,
                package_detail_visible: false,
                show_detail: '', //当前dialog显示的包
                content_dialog: '', //需要显示的具体内容
                content_visible: false
            }
        },
        methods: {
            clear_this() {
                this.message_list = []
                this.show_message_list = []
                this.chat_map = {}
                this.page_list = []
                this.cur_page = 1
            },
            show_content(data) {
              this.content_visible = true
              this.content_dialog = data
            },
            get_key(data) {
                let key: string
                if (data.SrcIp.includes('192.168.')) {
                    key = data.SrcIp + ":" + data.SrcPort + "-" + data.DstIp + ":" + data.DstPort
                } else {
                    key = data.DstIp + ":" + data.DstPort + "-" + data.SrcIp + ":" + data.SrcPort
                }
                return key
            },
            db_show_chat(data) {
                clearTimeout(this.click_timer)
                let key = this.get_key(data)
                this.show_key = key
                this.page_list = []
                this.page_save = this.cur_page
                this.cur_page = 1
                this.show_message_list = this.chat_map[key]
                // console.log(this.show_message_list.length)
                this.get_page_data()
                this.show_type = '会话'
            },
            return_global() {
                this.show_key = ''
                this.page_list = []
                this.cur_page = this.page_save
                this.show_message_list = this.message_list
                // console.log(this.show_message_list.length)
                this.get_page_data()
                this.show_type = '全局'

            },
            handel_dev_change() {
                let return_dev = []
                for(let i in this.select_devices) {
                    if (this.select_devices[i]) {
                        return_dev.push(this.all_devices[i].Name)
                    }
                }
                SetNeedDevices(return_dev).then(res => {
                    ElMessage.success({
                        message: '切换成功',
                        duration: 1500,
                        center: true
                    })
                })
            },
            show_chat(data) {
                clearTimeout(this.click_timer)
                let that = this
                this.click_timer = setTimeout(function () {
                    that.package_detail_visible = true
                    data.DataString = data.DataString.replaceAll("\n", "<br/>")
                    data.DataString = '<span>' + data.DataString + '</span>'
                    that.show_detail = data
                    // console.log(data.DataString)
                }, 250)
            },
            get_proc() {
                const that = this
                clearInterval(this.search_inter)
                this.message_list = []
                this.show_message_list = []
                this.chat_map = {}
                this.page_list = []
                this.cur_page = 1
                this.proc_data = []
                this.search_inter = setInterval(() => {
                    GetProcIdByName(that.search_proc).then(res => {
                        // 去除res中没有且data有的元素
                        for (let j in that.proc_data) {
                            let labelT = that.proc_data[j].label
                            let isExist = false
                            for (let i in res) {
                                let label = res[i].Name + '-' + res[i].Pid
                                if (label === labelT) {
                                    isExist = true
                                    break
                                }
                            }
                            if (!isExist) {
                                that.proc_data.splice(parseInt(j), 1)
                            }
                        }
                        // 添加res中有且data没有的元素
                        let pushed_item_key = []
                        for (let i in res) {
                            let label = res[i].Name + '-' + res[i].Pid
                            let isExist = false
                            for (let j in that.proc_data) {
                                let labelT = that.proc_data[j].label
                                if (label == labelT) {
                                    isExist = true
                                    break
                                }
                            }
                            if (!isExist) {
                                that.proc_data.push({'label': label, 'id': res[i].Pid})
                                pushed_item_key.push(res[i].Pid)
                            }
                        }
                        if (pushed_item_key.length > 0) {
                            that.$nextTick(() => {
                                let checked_list = that.$refs['tree'].getCheckedKeys(true)
                                pushed_item_key.push(...checked_list)
                                // console.log(pushed_item_key)
                                that.$refs['tree'].setCheckedKeys(pushed_item_key, true)

                            })
                        }
                    })
                }, 1000)
            },
            tree_check_change(data, checked, b) {
                let select_data = this.$refs['tree'].getCheckedKeys(true)
                SetSelectPid(select_data)
            },
            append_log() {
                let that = this
                EventsOn('package_receive', (data) => {
                    data.data_bytes = new Uint8Array(atob(data.Data).split("").map(function (c) {
                        return c.charCodeAt(0)
                    }))
                    that.message_list.push(data)
                    let key = that.get_key(data)
                    if (this.chat_map[key] === undefined) {
                        this.chat_map[key] = [data]
                    } else {
                        this.chat_map[key].push(data)
                    }
                    // if (this.show_key != '') {
                    //     this.show_message_list = this.chat_map[key]
                    // }else {
                    //     this.show_message_list = this.message_list
                    // }
                    this.get_page_data()
                })
            },
            get_page_data() {
                let start = (this.cur_page - 1) * 22
                let end = start + 22
                this.page_list = this.show_message_list.slice(start, end)
            },
            cur_change(val) {
                this.cur_page = val
                this.get_page_data()
            }
        }
    }
</script>

<style>
    .el-dialog__body {
        padding: 10px !important;
    }
    .el-dialog__header {
        padding: 10px !important;
    }
</style>